package spring.boot.config;


import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import spring.boot.security.MyFilterSecurityInterceptor;


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启security的注解
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private MyFilterSecurityInterceptor myFilterSecurityInterceptor;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;
    
    @Autowired
    private DataSource dataSource;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf() //跨站
                .disable() //关闭跨站检测
                .authorizeRequests() //验证策略
                .antMatchers("/index").permitAll()
                .antMatchers("/login").permitAll()
                .antMatchers("/img/**").permitAll()
                .antMatchers("/js/**").permitAll()
                .antMatchers("/css/**").permitAll()
                .antMatchers("/bootstrap/**").permitAll()
                .antMatchers("/fonts/**").permitAll()
                .antMatchers("/favicon.ico").permitAll()
                .anyRequest()       //所有请求
                .authenticated()    //必须验证
                .and()
                .formLogin()
                .loginPage("/login")
                .failureUrl("/login?error=1")//自定义登录页
                .permitAll()
                .successHandler(authenticationSuccessHandler)   // 与defaultSuccessUrl只能使用一个
                //.defaultSuccessUrl("/welcome",true) //登录成功后跳转页
                //.permitAll()
                .and()  
                .rememberMe()//登录后记住用户，下次自动登录,数据库中必须存在名为persistent_logins的表  
                .rememberMeParameter("rememberMe")  // input的name值
                .tokenRepository(persistentTokenRepository())  //
                .tokenValiditySeconds(1209600) // 设置cookie存储的时间（以秒为单位）
                .and()
                .exceptionHandling()
                .accessDeniedPage("/myerror");//无权访问
        // 添加我们自定义的拦截器
        http	.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
    }

	/* (non-Javadoc)
	 * 校验密码逻辑
	 * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder)
	 */
	@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
            .passwordEncoder(new PasswordEncoder(){
            	
                @Override
                public String encode(CharSequence arg0) {
                    return arg0.toString();
                }

                @Override
                public boolean matches(CharSequence arg0, String arg1) {
                    return arg1.equals(arg0.toString());
                }
            	
            });
        auth.eraseCredentials(false); //不允许清除密码（使用RememberMe功能）
    }
	
    @Bean // 使用RememberMe功能
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
        db.setDataSource(dataSource);
        return db;
    }
}
